第5节 函数和作用域大纲

【金山文档】 函数思维导图(复习)

https://kdocs.cn/l/sjIl7tCyXsK6

前言: 完成以下练习

编写代码:计算 1-100 相加并输出结果, 计算 1-200 相加,并输出结果, 计算 1-300 相加,并输出结果

没学函数前, 我们可能会写三遍 for 循环, 有了函数之后只需要写一遍即可.

(一)函数的声明函数的调用

函数就是封装(打包)多行函数, 元素函数就是运行函数封装的多行代码

  1. 函数声明和调用
  2. 对象中的函数(方法), alert 就是 window 对象的一个方法
  3. 函数和变量声明提前
  4. 函数表达式

(1)函数的声明和调用

  1. 声明函数 fuction xxx() {}
  2. 调用函数 xxx(), 函数被调用的时候, 函数体(函数内部的代码)才会运行
  3. js代码的运行分两步:
    • 先解析代码
    • 运行代码
  4. 函数和变量的声明会提前
    • 函数是"一等公民", 程序运行的时候, 不管函数定义在什么位置, 都会先执行声明, 所以在任何地方都可以调用函数.
    • 变量也会一开始运行就声明, 等到代码运行到变量声明的那句代码才可以对其进行赋值
<script>
  // 调用函数
  sum();
  console.log('ghkjhkhk');
  // 声明函数
  function sum() {
    var count=0;
    for(var i=0;i<100;i++) {
      count+=i;
    }
    console.log('count',count);
  }  
  // 调用函数
  sum();
</script>
    
    
<script>
	console.log('str',str); // 不会报错,输出undefined
    var str = 'hello';
	console.log('str',str); // hello
</script>    

(2) 对象中的方法

定义在对象中的函数就是对象的方法, 下面say函数是obj对象的一个方法

alert, console, prompt都是window对象的方法

<script>
  var obj = {
    name: 'zhangsan',
    age: 18,
    say: function() {
      console.log('它是张三');
    }
  }
  obj.say();
</script> 

(3) 函数表达式(先了解)

使用函数表达式来创建函数的时候, 调用函数必须放在函数之后

<script> 
  // 使用函数表达式时, say在这里还没赋值, 所以它的值就是undefined, 所以不能调用
  console.log('say',say); 
  var say = function () {
    console.log('它居然会说话')
  };
  // 必须在赋值之后去调用(就是在表达式之后才能调用)
  say();
</script>

(二)函数的调用方式

(1) 手动调用

(2) 绑定一个事件来触发函数的运行

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width='device-width', initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <button onclick="say()">按钮</button>
 
  <script>
    function say(){
      console.log('哈哈哈哈哈');
    }
    // 调用函数
    say();
  </script>
</body>
</html>

// 练习

  1. 写一个函数,实现50 到 500 相加, 并输出到网页上

     <script>
        function sum() {
          var total = 0;
          for(var i=50;i<=500;i++) {
            total += i;
          }
          document.write(total);
        }
        sum();
      </script>
    
  2. 需求: 从页面上输入两个加数,绑定事件,计算两个加数相加的结果,并显示在页面上

    <!DOCTYPE html>
    <html lang="en"> 
    <body>
      <input class="num"> + <input class="num"> 
      <button onclick="add()">=</button> 
      <span id="sum">?</span>
      <script>
         function add() {
           // 获取两个input元素对象
           var $inputs = document.querySelectorAll('.num');
          // 获取第一个input的值
           var num1 = $inputs[0].value; 
          // 获取第二个input的值
           var num2 = $inputs[1].value; 
          // 两个加数相加,赋值给sum
           var sum = num1*1 + num2*1;
           var $sum = document.querySelector('#sum');
           $sum.innerHTML = sum;
         }
      </script>
    </body>
    </html>
    
    // 代码调试例子
    <body>
        <input class="num" type="text">+<input class="num" type="text"><button onclick="sum()">=</button>
        <span id="app">?</span>
        <script>
            function sum(){
                var $num = document.querySelectorAll('.num');
                var $num1 = $num[0].value;
                var $num2 = $num[1].value;
                var $app = document.querySelector('#app');
                $app.innerTxet= $num1*1+ $num2*1;
                console.log($app)
            }
        </script>
    </body>
    

(三)函数传递参数(重要)

  1. 调用函数可以通过()传入任意类型参数, 被调用函数通过()接收参数(demo1)
    • 调用时传入什么数据,函数就接收到什么数据
    • 传入的参数可以是任何类型
  2. 传入的参数叫实参, 接收的参数叫形参, 形参和实参位置一一对应
  3. 基本数据类型和引用数据类型参数的区别(先了解)
<!-- demo1 -->
<!DOCTYPE html>
<html lang="en"> 
<body> 
  <script>
      function say(a) {
        console.log(a);
      } 
      say(100);
      say('abcd');
      say({name:'zhangsan',age: 100});
  </script>
</body>
</html>    
      
<!-- demo2 -->
<!DOCTYPE html>
<html lang="en"> 
<body> 
  <script>
      var a = 100;
      var b = 200;
      say(a,b);

      function say(x,y) {
        console.log(x,y);
      } 
  </script>
</body>
</html>      

// 练习:

  1. 编写一个任意两数相加的函数, 调用函数将结果输出在控制台
  2. 编写一个累加的函数,用户输入任意两个数都能计算累加的结果, 比如: 用户输入10,20, 则将10~20累加
<!DOCTYPE html>
<html lang="en"> 
<body> 
  <script>
       // 第1题
       function add(a,b) {
        var sum = a*1+b*1;
        console.log(sum);
       }

       add(10,20);
       add(100,200);  
  </script>
</body>
</html>
<script>
  // 第2题    
  function sum(x,y) {
    var total = 0;
    for (var i = x; i <= y; i++) {
      total += i;
    }
    console.log(total);
  }

  sum(1,100);
  sum(15,25);
</script>

(四)函数返回值

4.1 使用 return 返回计算的结果(是否需要返回根据你自己的需要) 4.2 没写 return,默认返回 undefined

<script>
    function add(a,b) {
      var sum = a+b;
      return sum;
    }

    var sum = add(10,20);
    console.log('调用结果',sum);
</script>
    
<script>
    function add(a,b) {
      var sum = a+b;
      console.log(sum);
    }

    var sum = add(10,20);
    console.log('调用结果',sum); // undefined
</script>    

// 练习 练习 4. 需求: 声明一个函数,实现 1 到任意数字累加的结果

(五)作用域

什么是作用域?

答: 变量的作用域指的是变量起作用的领域(范围)就是变量的作用域.

  1. 作用域和变量
  2. 作用域访问规则

(1) 作用域和变量

  1. 全局作用域和全局变量: 全局作用域就是window,在window下定义的变量就是全局变量

    var num = 100; // 全局变量num会自动的变成window的一个属性
    window.num2 = 200;
    console.log(window.num2);
    consoel.log(num2);  // 全局变量可以直接访问, 省略window.
    
  2. 函数运行时, 函数内部就形成了局部作用域, 在函数内部声明的变量就是局部变量

    局部变量在函数运行的时候存在, 函数运行结束就被销毁

    ps: 区分全局和局部变量的标准就是看这个变量是否是在函数内声明的

  <script>
    // num是全局变量
    var num = 100; 
	// sum,a,b都是局部变量, 因为它们都是函数add内
    function add(a, b) {
      var sum = a + b;
      return sum;
    } 
  </script> 
  1. js没有块级作用域(后台语言有块级作用域, 以{}进行区分)

    解释: js的作用域以函数作为区分标准, 而不是以{}作为区分标准

    <script> 
        for(var i=0;i<5;i++) {
          console.log(2222);
        } 
        console.log(i);
    </script>
    

(4) 作用域规则

  1. 函数内部可以访问函数外部的变量

  2. 函数外部不可以访问函数内部的变量

    <script>
      var x = 100; 
      function aa() {
        var y = 200;
        console.log(x); // 里面可以访问外面
      } 
      aa();  
      console.log(y);  // 外面无法访问里面
    </script>
    
  3. 多个嵌套的作用域形成了作用域链

    当访问一个变量时, 从最近的作用域开始查找, 若没有就查找向上一层作用域, 一直到全局作用域为止, 若找到就返回, 找不到就报错"xxx is not defined"

    <script>
      var x = 100; 
      function aa() {
        var a = 10;
        function bb() {
          var b = 20;
          function cc() {
            var c = 30;
             console.log(x);
             console.log(y);
          }
          cc();
        }
        bb();
      } 
      aa();   
    </script>
    

作业:

  1. 使用函数的方式重写电影列表和影院列表页面

  2. 编写一个简单计算器(eval 用来计算)

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <link rel="stylesheet" href="./style.css"> 
    </head>
    
    <body>
        <div class="box">
    
            <div class="inp-box">
                <input id="inp" class="inp" type="text" placeholder="简单计算器">
            </div>
            <ul class="list">
                <li>C</li>
                <li>CE</li>
                <li>%</li>
                <li>/</li>
                <li>7</li>
                <li>8</li>
                <li>9</li>
                <li>x</li>
    
                <li>4</li>
                <li>5</li>
                <li>6</li>
                <li>-</li>
                <li>1</li>
                <li>2</li>
                <li>3</li>
                <li>+</li>
    
                <li style="width: 210px;">0</li>
                <li>.</li>
                <li>=</li>
            </ul>
        </div>  
    </body> 
    </html>
    
    * {
      margin: 0;
      padding: 0;
    }
    ul,
    li {
      list-style: none;
    }
    .box {
      margin-top: 100px;
      width: 440px;
      background-color: #ebebeb;
      margin: 0 auto;
      padding: 5px;
    }
    .inp-box {
      height: 50px;
      display: flex;
      justify-content: center;
      align-items: center;
      margin-bottom: 5px;
    }
    .inp-box .inp {
      width: 100%;
      height: 45px;
      border: none;
      text-indent: 20px;
      font-size: 25px;
      outline: none;
    }
    .list {
      display: flex;
      flex-wrap: wrap;
      justify-content: space-between;
    }
    .list li {
      user-select: none;
      width: 100px;
      height: 65px;
      text-align: center;
      line-height: 65px;
      font-size: 20px;
      background-color: #fff;
      margin-bottom: 10px;
      cursor: pointer;
    }